#include "PCM_sinkGlue.h"
#include "Bridger.h"

#include "reaper_plugin/reaper_plugin.h"

#include "luna.h"

#include <assert.h>

class BridgePCM_sink;
mkchelpers(PCM_sink);

class BridgePCM_sink : public Bridger
{
public:
	BridgePCM_sink(lua_State *L) : Bridger(L)	{}

// f-unctions exposed to Lua
	//virtual void GetOutputInfoString(char *buf, int buflen)=0;
	// takes {self} returns string
	int fGetOutputInfoString(lua_State *L)
	{
		char *buf = new char[BUFSIZ];
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		sink->GetOutputInfoString(buf, BUFSIZ);
		lua_pushstring(L, buf);
		delete buf;
		return 1;
	}

	//virtual double GetStartTime() { return m_st; }
// takes {self} returns double
	int fGetStartTime(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);

		double st = sink->GetStartTime();
		lua_pushnumber(L, st);
		return 1;
	}

	// virtual void SetStartTime(double st) { m_st=st; }
// takes ( {self}, double ) returns void
	int fSetStartTime(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		double st = luaL_checknumber(L, 2);
		sink->SetStartTime(st);
		return 0;
	}

	//virtual const char *GetFileName()=0; // get filename, if applicable (otherwise "")
// takes {self} returns string
	int fGetFileName(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		const char *fname = sink->GetFileName();
		assert(fname != NULL);
		lua_pushstring(L, fname);
		return 1;
	}

//virtual int GetNumChannels()=0; // return number of channels
// takes {self} returns int
	int fGetNumChannels(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		int nchan = sink->GetNumChannels();
		lua_pushnumber(L, nchan);
		return 1;
	}

	//    virtual double GetLength()=0; // length in seconds, so far
// takes {self} returns double
	int fGetLength(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		double length = sink->GetLength();
		lua_pushnumber(L, length);
		return 1;
	}

	//    virtual INT64 GetFileSize()=0;
	int fGetFileSize(lua_State *L)
	{
		PCM_sink *sink = (PCM_sink *) toReaperObject(L, 1);
		long int fileSize = (long int) sink->GetFileSize();
		lua_pushnumber(L, fileSize);
		return 1;
	}

// luna wrapper interface:
public:
	static const char className[];
    static const Luna<BridgePCM_sink>::RegType Register[];
};

#define psoreg(NAME) \
{	#NAME , &BridgePCM_sink::f##NAME }

const char BridgePCM_sink::className[] = "ReaperPCM_sink";
const Luna<BridgePCM_sink>::RegType BridgePCM_sink::Register[] = {
	psoreg(GetOutputInfoString),
	psoreg(GetStartTime),
	psoreg(SetStartTime),
	psoreg(GetFileName),
	psoreg(GetNumChannels),
	psoreg(GetLength),
	psoreg(GetFileSize),
	{NULL, NULL}
};
